
#include "StringManager.h"

using namespace unigame;

int32 StringManager::utf8String(char *src, int32 len, uint16 *dest)
{
    int32 temp = 0;
    int32 result = 0;
    int32 pointer = 0;
    for(int32 i = 0; i < len; ++i, ++pointer)
    {
        int32 count = 1;
        if((src[i] & 0x80) > 0)
        {
            ++count;
            if((src[i] & 0x20) > 0)
            {
                ++count;
            }
        }
        switch(count)
        {
            case 1:
                result = src[i];
                break;
            case 2:
                temp = (src[i++] & 0x1f) << 6;
                result = temp;
                temp = src[i] & 0x3f;
                result |= temp;
                break;
            case 3:
                temp = (src[i++] & 0xf) << 12;
                result = temp;
                temp = (src[i++] & 0x3f) << 6;
                result |= temp;
                temp = src[i] & 0x3f;
                result |= temp;
                break;
            default:
                break;
        }
        if(dest)
        {
            dest[pointer] = (uint16)result;
        }
    }
    if(dest)
    {
        dest[pointer] = 0;
    }
    return pointer;
}

int32 StringManager::utf8String(char *src, wchar_t *dest)
{
    int32 temp = 0;
    int32 result = 0;
    int32 pointer = 0;
    int32 len = strlen(src);
    for(int32 i = 0; i < len; ++i, ++pointer)
    {
        int32 count = 1;
        if((src[i] & 0x80) > 0)
        {
            ++count;
            if((src[i] & 0x20) > 0)
            {
                ++count;
            }
        }
        switch(count)
        {
            case 1:
                result = src[i];
                break;
            case 2:
                temp = (src[i++] & 0x1f) << 6;
                result = temp;
                temp = src[i] & 0x3f;
                result |= temp;
                break;
            case 3:
                temp = (src[i++] & 0xf) << 12;
                result = temp;
                temp = (src[i++] & 0x3f) << 6;
                result |= temp;
                temp = src[i] & 0x3f;
                result |= temp;
                break;
            default:
                break;
        }
        if(dest)
        {
            dest[pointer] = result;
        }
    }
    if(dest)
    {
        dest[pointer] = 0;
    }
    return pointer;
}

int32 StringManager::uniFindChar(uint16 ch, const uint16 *str, int32 start, int32 end)
{
    for(; start != end; ++start)
    {
        if(ch == str[start])
        {
            return start;
        }
        else if(str[start] == 0)
        {
            return -1;
        }
    }
    return -1;
}

int32 StringManager::uniCompare(const uint16 *str1, const uint16 *str2)
{
    int32 i = 0;
    while(str1[i] != 0 && str2[i] != 0)
    {
        if(str1[i] != str2[i])
        {
            return str1[i] < str2[i]? -1: 1;
        }
        ++i;
    }
    if(str1[i] == 0 && str2[i] == 0)
    {
        return 0;
    }
    if(str1[i] == 0)
    {
        return -1;
    }
    return 1;
}

int32 StringManager::uniCompare(const uint16 *str1, const char* str2)
{
    int32 i = 0;
    while(str1[i] != 0 && str2[i] != 0)
    {
        if(str1[i] != str2[i])
        {
            return str1[i] < str2[i]? -1: 1;
        }
        ++i;
    }
    if(str1[i] == 0 && str2[i] == 0)
    {
        return 0;
    }
    if(str1[i] == 0)
    {
        return -1;
    }
    return 1;
}

int32 StringManager::uniFindNextNotBlank(const uint16 *str, int32 start, int32 end)
{
    for(; start != end; ++start)
    {
        if(str[start] == 0)
        {
            return -1;
        }
        if(str[start] > ' ')
        {
            return start;
        }
    }
    return -1;
}

void StringManager::uniTrimStr(const uint16 *str, int32 *start, int32 *end)
{
	while(*start < *end)
	{
		if(str[*start] <= ' ')
		{
			++(*start);
		}
        else
        {
            break;
        }
	}
	if(*start == *end)
	{
		return;
	}
	--(*end);
	while(*end >= *start)
	{
		if(str[*end] <= ' ')
		{
			--(*end);
		}
        else
        {
            break;
        }
	}
	++(*end);
}

int32 StringManager::uniLength(const uint16 *str)
{
    int32 count = 0;
    while(str[count] != 0)
    {
        ++count;
    }
    return count;
}